﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestAddFactorRMFlattenDenseMatrix.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.RMFlattenDenseMatrixTest.DoubleExtensions
{
    #region Usings

    using System;

    using ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for
    ///     <see cref="RMFlattenDenseMatrixExtensions.Add(RMFlattenDenseMatrix{double},double,RMFlattenDenseMatrix{double})"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions.RMDenseMatrix1DSExtensions")]
    public sealed class TestAddFactorRMFlattenDenseMatrix
    {
        /// <summary>
        ///     Tests the method when augend and addend have the same size.
        /// </summary>
        [Test]
        public void WhenAugendAndAddendHaveTheSameSize()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15, 20,
                                 25, 30, 35
                             };
            var addend = new RMFlattenDenseMatrix<double>(2, 3, addendData);
            var expected = new[]
                           {
                               20, 35, 50,
                               65, 80, 95
                           };

            // Act
            augend.Add(10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when addend has less count of rows than augend.
        /// </summary>
        [Test]
        public void WhenAddendHasLessRowsCountThanAugend()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15, 20
                             };
            var addend = new RMFlattenDenseMatrix<double>(1, 3, addendData);
            var expected = new[]
                           {
                               20, 35, 50,
                               4, 5, 6
                           };

            // Act
            augend.Add(10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when addend have greater count of rows than augend.
        /// </summary>
        [Test]
        public void WhenAddendHasGreaterRowsCountThanAugend()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15, 20,
                                 25, 30, 35,
                                 40, 45, 50
                             };
            var addend = new RMFlattenDenseMatrix<double>(3, 3, addendData);
            var expected = new[]
                           {
                               20, 35, 50,
                               65, 80, 95
                           };

            // Act
            augend.Add(10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when addend has less count of columns than augend.
        /// </summary>
        [Test]
        public void WhenAddendHasLessColumnsCountThanAugend()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15,
                                 20, 25
                             };
            var addend = new RMFlattenDenseMatrix<double>(2, 2, addendData);
            var expected = new[]
                           {
                               20, 35, 3,
                               60, 75, 6
                           };

            // Act
            augend.Add(10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when addend has greater count of columns than augend.
        /// </summary>
        [Test]
        public void WhenAddendHasGreaterColumnsCountThanAugend()
        {
            // Arrange
            var augendData = new double[]
                             {
                                 1, 2, 3,
                                 4, 5, 6
                             };
            var augend = new RMFlattenDenseMatrix<double>(2, 3, augendData);
            var addendData = new double[]
                             {
                                 10, 15, 20, 25,
                                 30, 35, 40, 45
                             };
            var addend = new RMFlattenDenseMatrix<double>(2, 4, addendData);
            var expected = new[]
                           {
                               20, 35, 50,
                               70, 85, 100
                           };

            // Act
            augend.Add(10, addend);

            // Assert
            Assert.That(augend.Values, Is.EquivalentTo(expected));
        }

#if SAFE

        /// <summary>
        ///     Tests the method when augend is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenAugendIsNull()
        {
            // Arrange
            var addend = new RMFlattenDenseMatrix<double>(2, 3);

            // Act and Assert
            Assert.That(
                () => RMFlattenDenseMatrixExtensions.Add(null, 10, addend),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("augend"));
        }

        /// <summary>
        ///     Tests the method when addend is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenAddendIsNull()
        {
            // Arrange
            var augend = new RMFlattenDenseMatrix<double>(2, 3);

            // Act and Assert
            Assert.That(
                () => augend.Add(10, null),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("addend"));
        }

#endif
    }
}